package com.xbongbong.saas.service.toolbox.help;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasFormDataEntity;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt;
import com.xbongbong.paas.elasticsearch.pojo.XbbAggregatedPage;
import com.xbongbong.paas.elasticsearch.util.EsHelper;
import com.xbongbong.paas.elasticsearch.util.EsUtil;
import com.xbongbong.paas.elasticsearch.util.XbbElasticsearchRestTemplate;
import com.xbongbong.paas.enums.DateTimeEnum;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.help.BusinessUserTeamHelp;
import com.xbongbong.paas.help.CommonHelp;
import com.xbongbong.paas.help.subform.WarehouseTeamTransferSubForm;
import com.xbongbong.paas.model.PaasFormExplainModel;
import com.xbongbong.paas.model.PaasFormModel;
import com.xbongbong.paas.model.PaasUserModel;
import com.xbongbong.paas.pojo.dto.ValidateDataDTO;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CloneUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.toolbox.wrap.UserVO;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.pro.constant.CommonConstant;
import com.xbongbong.pro.constant.ElasticConstant;
import com.xbongbong.pro.domain.entity.FormTeamSetEntity;
import com.xbongbong.pro.enums.DistributorMarkEnum;
import com.xbongbong.pro.enums.FieldAdvanceOperationEnum;
import com.xbongbong.pro.enums.PackageTypeEnum;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.errorcodes.BusinessTypeErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.UserTeamErrorCodeEnum;
import com.xbongbong.pro.enums.permission.enums.ProPermissionAliasEnum;
import com.xbongbong.pro.enums.teammembers.enums.CoUserPermissionEnum;
import com.xbongbong.pro.enums.teammembers.enums.FormCoUserDefaultPermissionEnum;
import com.xbongbong.pro.enums.teammembers.enums.FormDefaultPatternEnum;
import com.xbongbong.pro.enums.teammembers.enums.FormPatternEnum;
import com.xbongbong.pro.enums.teammembers.enums.TeamEditBusinessEnum;
import com.xbongbong.pro.formdata.pojo.dto.FormDataDetailDTO;
import com.xbongbong.pro.formexplain.pojo.dto.HandlerExplainDTO;
import com.xbongbong.pro.log.pojo.DetailLogPojo;
import com.xbongbong.pro.model.FormTeamSetModel;
import com.xbongbong.pro.statistic.result.pojo.ElasticAggsPojo;
import com.xbongbong.pro.user.pojo.ReturnUserAndDepartmentPojo;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.ParameterConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.constant.teammembers.TeamMembersConstant;
import com.xbongbong.saas.domain.entity.UserAndDepTeamEntity;
import com.xbongbong.saas.domain.entity.UserTeamEntity;
import com.xbongbong.saas.domain.entity.WarehouseUserEntity;
import com.xbongbong.saas.enums.UserTeamEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.ClueEnum;
import com.xbongbong.saas.enums.business.ContactEnum;
import com.xbongbong.saas.enums.business.CustomerManagementEnum;
import com.xbongbong.saas.enums.business.MarketActivityEnum;
import com.xbongbong.saas.enums.business.SupplierContactEnum;
import com.xbongbong.saas.enums.business.SupplierEnum;
import com.xbongbong.saas.enums.subform.SubFormTransferEnum;
import com.xbongbong.saas.model.BomUserModel;
import com.xbongbong.saas.model.ClueUserModel;
import com.xbongbong.saas.model.ContactUserModel;
import com.xbongbong.saas.model.ContractUserModel;
import com.xbongbong.saas.model.CustomerUserModel;
import com.xbongbong.saas.model.IndexTypeModel;
import com.xbongbong.saas.model.MarketActivityUserModel;
import com.xbongbong.saas.model.OpportunityUserModel;
import com.xbongbong.saas.model.PayPlanSheetUserModel;
import com.xbongbong.saas.model.PayPlanUserModel;
import com.xbongbong.saas.model.PaymentSheetUserModel;
import com.xbongbong.saas.model.PaymentUserModel;
import com.xbongbong.saas.model.ProductUserModel;
import com.xbongbong.saas.model.ProductionOrderUserModel;
import com.xbongbong.saas.model.PurchaseUserModel;
import com.xbongbong.saas.model.QuotationUserModel;
import com.xbongbong.saas.model.RefundUserModel;
import com.xbongbong.saas.model.SupplierContactUserModel;
import com.xbongbong.saas.model.SupplierUserModel;
import com.xbongbong.saas.model.WarehouseUserModel;
import com.xbongbong.saas.model.WorkOrderExplainModel;
import com.xbongbong.saas.model.WorkOrderFlowUserModel;
import com.xbongbong.saas.model.team.UserAndDepTeamModel;
import com.xbongbong.saas.model.team.UserTeamModel;
import com.xbongbong.saas.toolbox.help.FastJsonHelper;
import com.xbongbong.sys.domain.entity.UserEntity;
import com.xbongbong.sys.enums.DataPermissionEnum;
import com.xbongbong.sys.model.UserModel;
import org.apache.commons.collections4.CollectionUtils;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
import static org.elasticsearch.index.query.QueryBuilders.termsQuery;

/**
 * @description: 协同团队帮助类
 * @Author: hongxiao
 * @date: 2019-06-01 15:41
 * @since v1.0
 */
@Component
public class UserTeamHelp {
    @Resource
    private CustomerUserModel customerUserModel;
    @Resource
    private OpportunityUserModel opportunityUserModel;
    @Resource
    private ContractUserModel contractUserModel;
    @Resource
    private SupplierUserModel supplierUserModel;
    @Resource
    private SupplierContactUserModel supplierContactUserModel;
    @Resource
    private PaymentUserModel paymentUserModel;
    @Resource
    private PurchaseUserModel purchaseUserModel;
    @Resource
    private BomUserModel bomUserModel;
    @Resource
    private ProductionOrderUserModel productionOrderUserModel;
    @Resource
    private ContactUserModel contactUserModel;
    @Resource
    private PayPlanUserModel payPlanUserModel;
    @Resource
    private RefundUserModel refundUserModel;
    @Resource
    private WorkOrderFlowUserModel workOrderFlowUserModel;
    @Resource
    private ProductUserModel productUserModel;
    @Resource
    private QuotationUserModel quotationUserModel;
    @Resource
    private UserModel userModel;
    @Resource
    private ClueUserModel clueUserModel;
    @Resource
    private MarketActivityUserModel marketActivityUserModel;
    @Resource
    private PaasFormExplainModel paasFormExplainModel;
    @Resource
    private WorkOrderExplainModel workOrderExplainModel;
    @Resource
    private BusinessUserTeamHelp businessUserTeamHelp;
    @Resource
    private PaymentSheetUserModel paymentSheetUserModel;
    @Resource
    private PayPlanSheetUserModel payPlanSheetUserModel;
    @Resource
    private PaasUserModel paasUserModel;
    @Resource
    private FormTeamSetModel formTeamSetModel;
    @Resource
    private XbbElasticsearchRestTemplate xbbElasticsearchRestTemplate;
    @Resource
    private CommonHelp commonHelp;
    @Resource
    private PaasFormModel paasFormModel;
    @Resource
    private WarehouseUserModel warehouseUserModel;
    @Resource
    private WarehouseTeamTransferSubForm warehouseTeamTransferSubForm;
    @Resource
    private IndexTypeModel indexTypeModel;
    @Resource
    private EsHelper esHelper;
    @Resource
    private UserAndDepTeamModel userAndDepTeamModel;
    @Resource
    private UserTeamModel userTeamModel;

    public void checkPermissionOptionTeam(ValidateDataDTO validateDataDTO) throws XbbException{
        if (CollectionsUtil.isEmpty(validateDataDTO.getOwnerIds())) {
            return;
        }
        Long formId = validateDataDTO.getFormId();
        String corpid = validateDataDTO.getCorpid();
        // 权限处理
        PaasFormExplainEntity explainEntity = paasFormExplainModel.getByFormId(formId, corpid);
        if (Objects.isNull(explainEntity)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
        }
        Map<String, FieldAttrEntity> explainMap = ExplainUtil.getExplainMap(explainEntity.getExplains(), null);
        specialBusinessHandle(validateDataDTO,explainMap);
    }

    private void specialBusinessHandle(ValidateDataDTO validateDataDTO,Map<String, FieldAttrEntity> explainMap) throws XbbException{
        FieldAttrEntity ownerFieldAttr = explainMap.get(FieldTypeEnum.OWNERID.getAlias());
        if (Objects.isNull(ownerFieldAttr)) {
            return;
        }
        // 新的负责人
        List<String> newMainUserList = new ArrayList<>();
        // 老的负责人
        List<String> oldMainUserList = validateDataDTO.getOldOwnerId() == null ? new ArrayList<>() : Collections.singletonList(validateDataDTO.getOldOwnerId());
        validateDataDTO.getOwnerIds().forEach(owner->newMainUserList.add(Objects.toString(owner.getId(), "")));
        String creatorId = validateDataDTO.getCreatorId() == null ? validateDataDTO.getUserId() :validateDataDTO.getCreatorId();
        // 负责人
        List<String> copyNewMainList = (List<String>)CloneUtil.deepClone(newMainUserList);
        List<String> copyOldMainList = (List<String>)CloneUtil.deepClone(oldMainUserList);
        //获取当前登录人的信息
        UserEntity userEntity = new UserEntity();
        BeanUtil.copyProperties(validateDataDTO.getLoginUser(),userEntity);

        //Integer dataPermission = userModel.getDataPermission(userEntity);
        List<String> subIdList = userModel.getManageUser(userEntity);
        //采购退货单、装配出入库单、入库单、出库单、盘点单、调拨单 只有负责人
        HandlerExplainDTO handlerExplainDTO = new HandlerExplainDTO();
        BeanUtil.copyProperties(validateDataDTO, handlerExplainDTO);
        handlerExplainDTO.setCreatorId(creatorId);
        handlerExplainDTO.setOwnerId(oldMainUserList);
        handlerExplainDTO.setSubIdList(subIdList);
        String userId = validateDataDTO.getUserId();
        if (StringUtil.isNotEmpty(validateDataDTO.getProcessCreatorId())) {
            userId = validateDataDTO.getProcessCreatorId();
            //  已在在审批里处理，edit by 吴峰 date 2021/7/29 10:11
//            UserVO userVO = userService.getUserVO(validateDataDTO.getCorpid(), userId, true, true);
//            handlerExplainDTO.setLoginUser(userVO);
        }
        handlerExplainDTO.setUserId(userId);
        Boolean haveMainAddPermission = ExplainUtil.advancedOperationHavePermission(ownerFieldAttr, handlerExplainDTO, FieldAdvanceOperationEnum.ADD.getOperation());
        Boolean haveMainDelPermission = ExplainUtil.advancedOperationHavePermission(ownerFieldAttr, handlerExplainDTO, FieldAdvanceOperationEnum.DEL.getOperation());

        if(CollectionsUtil.isEmpty(copyNewMainList) && CollectionsUtil.isEmpty(copyOldMainList)){
            if(BasicConstant.ONE.equals(ownerFieldAttr.getRequired())) {
                if(haveMainAddPermission){
                    List<ReturnUserAndDepartmentPojo> ownerIds = validateDataDTO.getOwnerIds();
                    if(CollectionsUtil.isEmpty(ownerIds)){
                        ReturnUserAndDepartmentPojo returnUserAndDepartmentPojo = new ReturnUserAndDepartmentPojo();
                        returnUserAndDepartmentPojo.setId(userEntity.getId());
                        returnUserAndDepartmentPojo.setId(userEntity.getName());
                        returnUserAndDepartmentPojo.setAvatar(userEntity.getAvatar());
                        ownerIds.add(returnUserAndDepartmentPojo);
                    }
                }else {
                    throw new XbbException(UserTeamErrorCodeEnum.API_ERROR_390007,UserTeamErrorCodeEnum.API_ERROR_390007.getMsg());
                }
            }else {
                if(!haveMainAddPermission) {
                    throw new XbbException(UserTeamErrorCodeEnum.API_ERROR_390007, UserTeamErrorCodeEnum.API_ERROR_390007.getMsg());
                }
            }
        }else if(CollectionsUtil.isNotEmpty(copyNewMainList) && CollectionsUtil.isEmpty(copyOldMainList)){
            if(!haveMainAddPermission){
                throw new XbbException(UserTeamErrorCodeEnum.API_ERROR_390007,UserTeamErrorCodeEnum.API_ERROR_390007.getMsg());
            }
        }else if(CollectionsUtil.isEmpty(copyNewMainList) && CollectionsUtil.isNotEmpty(copyOldMainList)){
            if(!haveMainDelPermission){
                throw new XbbException(UserTeamErrorCodeEnum.API_ERROR_390005,UserTeamErrorCodeEnum.API_ERROR_390005.getMsg());
            }
        }else if(CollectionsUtil.isNotEmpty(copyNewMainList) && CollectionsUtil.isNotEmpty(copyOldMainList)){
            if(!haveMainDelPermission && !Objects.equals(copyNewMainList.get(0), copyOldMainList.get(0))) {
                throw new XbbException(UserTeamErrorCodeEnum.API_ERROR_390005,UserTeamErrorCodeEnum.API_ERROR_390005.getMsg());
            }else if(!haveMainAddPermission && !Objects.equals(copyNewMainList.get(0), copyOldMainList.get(0))){
                throw new XbbException(UserTeamErrorCodeEnum.API_ERROR_390007,UserTeamErrorCodeEnum.API_ERROR_390007.getMsg());
            }
        }
    }


    /**
     * 通用校验负责人和协同人, 编辑页离职校验, 编辑页不需要
     * 点击复制页进来, 已经离职的负责人/协同人不应该被添加
     *
     * @param isEdit 是否是编辑页进来的
     * @param isNew 是否是复制的
     */
    private void checkAddUserList(Boolean isEdit,
                                  Boolean isNew,
                                  String corpid,
                                  List<String> oldUserList,
                                  List<String> addUserList,
                                  List<String> copyOldList,
                                  List<String> delUserIdList) throws XbbException {
        //因为会处理负责人/协同人两次,delUserIdList要拷贝防止脏数据
        List<String> tempList = new ArrayList<>(delUserIdList);
        //取交集
        tempList.retainAll(oldUserList);
        //复制页进来的
        if (isNew) {
            //如果复制的负责人/协同人里有离职人员,则报错
            Optional.ofNullable(tempList)
                    .filter(t -> CollectionsUtil.isEmpty(t))
                    .orElseThrow(() -> new XbbException(SystemErrorCodeEnum.API_ERROR_100127));
        }
        //编辑页进来的
        else if (isEdit) {
            //编辑页里面需要有已离职校验,这里要添加到addCoUserList中让其报错
            addUserList.addAll(tempList);
            //去掉真正要删除的
            addUserList.removeAll(copyOldList);
        }

    }

    public void getAnotherUserIdMap(List<Long> dataIdList, String corpid, Integer businessType, Boolean isPublic, Map<Long, List<String>> mainUserIdMap, Map<Long, List<String>> coUserIdMap, List<Long> approveFailedList) {
        List<UserTeamEntity> userTeamEntityList = businessUserTeamHelp.getUserTeamList(dataIdList, corpid, businessType, isPublic, Arrays.asList(DelEnum.NORMAL.getDel(), DelEnum.APPROVE_FAILED.getDel()));
        for (UserTeamEntity entity : userTeamEntityList) {
            if (Objects.equals(DelEnum.APPROVE_FAILED.getDel(), entity.getDel())) {
                approveFailedList.add(entity.getId());
                continue;
            }
            if (Objects.equals(entity.getIsMain(),1)){
                if (mainUserIdMap.containsKey(entity.getDataId())) {
                    List<String> userId =  mainUserIdMap.get(entity.getDataId());
                    userId.add(entity.getUserId());
                    mainUserIdMap.put(entity.getDataId(), userId);
                } else {
                    List<String> userId = new ArrayList<>();
                    userId.add(entity.getUserId());
                    mainUserIdMap.put(entity.getDataId(), userId);
                }

            }else {
                if (coUserIdMap.containsKey(entity.getDataId())) {
                    List<String> userId =  coUserIdMap.get(entity.getDataId());
                    userId.add(entity.getUserId());
                    coUserIdMap.put(entity.getDataId(), userId);
                }else {
                    List<String> userId = new ArrayList<>();
                    userId.add(entity.getUserId());
                    coUserIdMap.put(entity.getDataId(), userId);
                }
            }
        }
    }
    /**
     * 获取用户团队
     *
     * @param dataIdList   数据id列表
     * @param corpid       公司id
     * @param businessType 业务类型
     * @param isPublic     是否公海，基本传false
     * @return
     * @throws
     * @author hongxiao
     * @date 2019-06-01 15:47
     * @version v1.0
     * @since v1.0
     */
    public List<UserTeamEntity> getUserTeamList(Collection<Long> dataIdList, String corpid, Integer businessType, Boolean isPublic, Integer isMain) {
        UserTeamEnum userTeamEnum = UserTeamEnum.getByCode(businessType);
        Map<String, Object> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        List<UserTeamEntity> userTeamEntityList;
        map.put("corpid", corpid);
        map.put("del", isPublic ? -1 : DelEnum.NORMAL.getDel());
        map.put("isMain", isMain);
        switch (userTeamEnum) {
            case CUSTOMER_TEAM:
            case DISTRIBUTOR_TEAM:
                map.put("customerIdIn", dataIdList);
                userTeamEntityList = customerUserModel.findBaseEntitys(map);
                break;
            case OPPORTUNITY_TEAM:
                map.put("opportunityIdIn", dataIdList);
                userTeamEntityList = opportunityUserModel.findBaseEntitys(map);
                break;
            case QUOTATION_TEAM:
                map.put("quotationIdIn", dataIdList);
                userTeamEntityList = quotationUserModel.findBaseEntitys(map);
                break;
            case CONTRACT_TEAM:
            case ORDER_TEAM:
                map.put("contractIdIn", dataIdList);
                userTeamEntityList = contractUserModel.findBaseEntitys(map);
                break;
            case SUPPLIER_TEAM:
                map.put("supplierIdIn", dataIdList);
                userTeamEntityList = supplierUserModel.findBaseEntitys(map);
                break;
            case SUPPLIER_CONTACT_TEAM:
                map.put("contactIdIn", dataIdList);
                userTeamEntityList = supplierContactUserModel.findBaseEntitys(map);
                break;
            case PAYMENT_TEAM:
                map.put("paymentIdIn", dataIdList);
                userTeamEntityList = paymentUserModel.findBaseEntitys(map);
                break;
            case PURCHASE_TEAM:
                map.put("purchaseIdIn", dataIdList);
                userTeamEntityList = purchaseUserModel.findBaseEntitys(map);
                break;
            case BOMBILL_TEAM:
                map.put("bomIdIn", dataIdList);
                userTeamEntityList = bomUserModel.findBaseEntitys(map);
                break;
            case PRODUCTIONORDER_TEAM:
                map.put("productionOrderIdIn", dataIdList);
                userTeamEntityList = productionOrderUserModel.findBaseEntitys(map);
                break;
            case CONTACT_TEAM:
            case DISTRIBUTOR_CONTACT_TEAM:
                map.put("contactIdIn", dataIdList);
                userTeamEntityList = contactUserModel.findBaseEntitys(map);
                break;
            case PAY_PLAN_TEAM:
                map.put("payPlanIdIn", dataIdList);
                userTeamEntityList = payPlanUserModel.findBaseEntitys(map);
                break;
            case REFUND_TEAM:
            case RETURN_TEAM:
                map.put("refundIdIn", dataIdList);
                userTeamEntityList = refundUserModel.findBaseEntitys(map);
                break;
            case WORK_ORDER_TEAM:
                map.put("workOrderIdIn", dataIdList);
                userTeamEntityList = workOrderFlowUserModel.findBaseEntitys(map);
                break;
            case PRODUCT_TEAM:
                map.put("dataIdIn", dataIdList);
                map.put("type", 0);
                List<UserAndDepTeamEntity> userAndDepTeamEntityList = productUserModel.findBaseEntitys(map);
                userTeamEntityList = new ArrayList<>();
                for (UserAndDepTeamEntity userAndDepTeamEntity : userAndDepTeamEntityList) {
                    UserTeamEntity userTeamEntity = new UserTeamEntity();
                    BeanUtil.copyProperties(userAndDepTeamEntity, userTeamEntity);
                    userTeamEntity.setUserId(userAndDepTeamEntity.getRelationId());
                    userTeamEntity.setIsMain(1);
                    userTeamEntityList.add(userTeamEntity);
                }
                break;
            case PAYMENT_SHEET_TEAM:
                map.put("dataIdIn", dataIdList);
                userTeamEntityList = paymentSheetUserModel.findBaseEntitys(map);
                break;
            case PAY_SHEET_TEAM:
                map.put("dataIdIn", dataIdList);
                userTeamEntityList = payPlanSheetUserModel.findBaseEntitys(map);
                break;
            case CLUE_TEAM:
                map.put("dataIdIn", dataIdList);
                userTeamEntityList = clueUserModel.findBaseEntitys(map);
                break;
            case MARKET_ACTIVITY_TEAM:
                map.put("dataIdIn", dataIdList);
                userTeamEntityList = marketActivityUserModel.findBaseEntitys(map);
                break;
            case PAAS_TEAM:
                map.put("dataIdIn", dataIdList);
                userTeamEntityList = paasUserModel.findBaseEntitys(map);
                break;
            case WAREHOUSE_TEAM:
                map.put("dataIdIn", dataIdList);
                map.put("type",BasicConstant.ZERO);
                List<WarehouseUserEntity> warehouseUserEntityList = warehouseUserModel.findEntitys(map);
                userTeamEntityList = warehouseTeamTransferSubForm.transferWarehouseUserToUserTeam(warehouseUserEntityList);
                break;
            case WORK_ORDER_V2_TEAM:
                map.put("dataIdIn", dataIdList);
                userTeamEntityList = userTeamModel.findBaseEntitys(map, "tb_work_order_v2_user");
                break;
            case RECEIPT_ORDER_TEAM:
                map.put("dataIdIn", dataIdList);
                userTeamEntityList = userTeamModel.findBaseEntitys(map, "tb_work_order_v2_receipt_order_user");
                break;
            case SLA_LOG_TEAM:
                map.put("dataIdIn", dataIdList);
                userTeamEntityList = userTeamModel.findBaseEntitys(map, "tb_sla_log_user");
                break;
            case SERVICE_PROJECT_TEAM:
                map.put("dataIdIn", dataIdList);
                List<UserAndDepTeamEntity> userAndDepTeamEntities = userAndDepTeamModel.findBaseEntitys(map, "tb_work_order_v2_service_project_user");
                userTeamEntityList = new ArrayList<>();
                for (UserAndDepTeamEntity userAndDepTeamEntity : userAndDepTeamEntities) {
                    UserTeamEntity userTeamEntity = new UserTeamEntity();
                    BeanUtil.copyProperties(userAndDepTeamEntity, userTeamEntity);
                    userTeamEntity.setUserId(userAndDepTeamEntity.getRelationId());
                    userTeamEntity.setIsMain(userAndDepTeamEntity.getType() == 1 ? 0 : 1);
                    userTeamEntityList.add(userTeamEntity);
                }
                break;
            default:
                return new ArrayList<>();
        }
        return userTeamEntityList;
    }


    /**
     * 获取用户团队
     *
     * @param dataIdList   数据id列表
     * @param corpid       公司id
     * @param businessType 业务类型
     * @param isPublic     是否公海，基本传false
     * @param mainUserIdMap   负责人idMap
     * @param coUserIdMap     协同idMap
     * @throws
     * @author hongxiao
     * @date 2019-06-01 15:47
     * @version v1.0
     * @since v1.0
     */
    public void setUserIdMap(Collection<Long> dataIdList, String corpid, Integer businessType, Boolean isPublic, Map<Long, List<String>> mainUserIdMap, Map<Long, List<String>> coUserIdMap) {
        List<UserTeamEntity> userTeamEntityList = getUserTeamList(dataIdList, corpid, businessType, isPublic, null);
        Map<String, Object> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        map.put(ParameterConstant.CORPID, corpid);
        map.put(ParameterConstant.DEL, DelEnum.DELETE.getDel());
        List<UserEntity> delUser = userModel.findEntitys(map);
        List<String> delUserIdList = new ArrayList<>();
        delUser.forEach(userEntity -> delUserIdList.add(userEntity.getUserId()));
        for (UserTeamEntity entity : userTeamEntityList) {
            if (delUserIdList.contains(entity.getUserId()) && !isPublic) {
                continue;
            }
            if (Objects.equals(entity.getIsMain(),1)){
                if (mainUserIdMap.containsKey(entity.getDataId())) {
                    List<String> userId =  mainUserIdMap.get(entity.getDataId());
                    userId.add(entity.getUserId());
                    mainUserIdMap.put(entity.getDataId(), userId);
                } else {
                    List<String> userId = new ArrayList<>();
                    userId.add(entity.getUserId());
                    mainUserIdMap.put(entity.getDataId(), userId);
                }

            }else {
                if (coUserIdMap.containsKey(entity.getDataId())) {
                    List<String> userId =  coUserIdMap.get(entity.getDataId());
                    userId.add(entity.getUserId());
                    coUserIdMap.put(entity.getDataId(), userId);
                }else {
                    List<String> userId = new ArrayList<>();
                    userId.add(entity.getUserId());
                    coUserIdMap.put(entity.getDataId(), userId);
                }
            }
        }
    }

    /**
     * 获取用户团队
     *
     * @param dataIdList   数据id列表
     * @param corpid       公司id
     * @param businessType 业务类型
     * @param isPublic     是否公海，基本传false
     * @param mainUserIdMap   负责人idMap
     * @param coUserIdMap     协同idMap
     * @throws
     * @author long.rao
     * @date 2020-05-07 15:48
     */
    public void getUserIdMap(Collection<Long> dataIdList, String corpid, Integer businessType, Boolean isPublic, Map<Long, List<String>> mainUserIdMap, Map<Long, List<String>> coUserIdMap, Map<Long, Set<String>> mainUserNameMap) {
        List<UserTeamEntity> userTeamEntityList = getUserTeamList(dataIdList, corpid, businessType, isPublic, null);
        Map<String, Object> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        map.put(ParameterConstant.CORPID, corpid);
        map.put(ParameterConstant.DEL, DelEnum.DELETE.getDel());
        List<UserEntity> delUser = userModel.findEntitys(map);
        List<String> delUserIdList = new ArrayList<>();
        delUser.forEach(userEntity -> delUserIdList.add(userEntity.getUserId()));
        for (UserTeamEntity entity : userTeamEntityList) {
            if (delUserIdList.contains(entity.getUserId()) && !isPublic) {
                continue;
            }
            if (Objects.equals(entity.getIsMain(),1)){
                if (mainUserIdMap.containsKey(entity.getDataId())) {
                    List<String> userId =  mainUserIdMap.get(entity.getDataId());
                    userId.add(entity.getUserId());
                    mainUserIdMap.put(entity.getDataId(), userId);
                } else {
                    List<String> userId = new ArrayList<>();
                    userId.add(entity.getUserId());
                    mainUserIdMap.put(entity.getDataId(), userId);
                }
                Set<String> mainUserName = mainUserNameMap.getOrDefault(entity.getDataId(), new HashSet<>());
                mainUserName.add(entity.getUserName());
                mainUserNameMap.put(entity.getDataId(), mainUserName);
            }else {
                if (coUserIdMap.containsKey(entity.getDataId())) {
                    List<String> userId =  coUserIdMap.get(entity.getDataId());
                    userId.add(entity.getUserId());
                    coUserIdMap.put(entity.getDataId(), userId);
                }else {
                    List<String> userId = new ArrayList<>();
                    userId.add(entity.getUserId());
                    coUserIdMap.put(entity.getDataId(), userId);
                }
            }
        }
    }

    public List<UserEntity> getUserTeamList(Collection<Long> dataIdList, String corpid, Integer businessType, Boolean isPublic, Integer isMain, boolean ignoreDel) {
        List<UserTeamEntity> userTeamEntityList = getUserTeamList(dataIdList, corpid, businessType, isPublic, isMain);
        Set<String> userIdSet = new HashSet<>();
        userTeamEntityList.forEach(item->{
            userIdSet.add(item.getUserId());
        });
        return userModel.getByUserIdIn(corpid, new ArrayList<>(userIdSet), ignoreDel);

    }

    /**
     * 获取当前表单是隔离模式还是共享模式
     *
     * @param corpid 公司id
     * @param formId 表单id
     * @param businessType 业务类型
     * @return true:共享  false:隔离
     */
    public boolean getFormShareTag(String corpid, Long formId, Integer businessType) throws XbbException {
        //非旗舰版套餐版本走的是默认共享模式
        Integer feeType = commonHelp.getCurrentCompanyPackage(corpid);
        //表单共享标识，true：共享  false：隔离
        boolean formShareTag = true;
        if (Objects.equals(feeType, PackageTypeEnum.ULTIMATE.getType())) {
            Map<String, Object> param = new HashMap<>();
            param.put(ParameterConstant.CORPID, corpid);
            param.put(ParameterConstant.FORMID, formId);
            param.put(ParameterConstant.DEL, BasicConstant.ZERO);
            param.put(ParameterConstant.BUSINESS_TYPE, businessType);
            List<FormTeamSetEntity> formTeamSetEntities = formTeamSetModel.findEntities(param);
            if (CollectionsUtil.isNotEmpty(formTeamSetEntities)) {
                FormTeamSetEntity formTeamSetEntity = formTeamSetEntities.get(BasicConstant.ZERO);
                Integer model = formTeamSetEntity.getModel();
                //隔离模式
                if (Objects.equals(model, FormPatternEnum.FORM_ISOLATION.getModel())) {
                    formShareTag = false;
                }
            } else {
                //这边就是要去取默认维护的关系
                formShareTag = FormDefaultPatternEnum.getModelByBusinessType(businessType);
            }
        }else {
            formShareTag = FormDefaultPatternEnum.getModelByBusinessType(businessType);
        }
        return formShareTag;
    }

    /**
     * 获取名称或编号map 迁移从ListBatchServiceImpl中的getEntityMap方法
     *
     * @param businessType
     * @param dataIdList
     * @param corpid
     * @param nameOrSeriNoMap
     * @throws XbbException
     * @author long.rao
     * @date 2020-04-03 15:28
     */
    public Map<Long, PaasFormDataEntity> getEntityMap(Integer businessType, List<Long> dataIdList, String corpid, Map<Long, String> nameOrSeriNoMap, Integer saasMark) throws XbbException{
        Map<Long, PaasFormDataEntity> entityMap = new HashMap<>(dataIdList.size());
        BoolQueryBuilder boolQueryBuilder = boolQuery();
        boolQueryBuilder.filter(termQuery("corpid.keyword",corpid));
        boolQueryBuilder.filter(termsQuery(FieldTypeEnum.DATAID.getAlias(), dataIdList));
        IndexTypeEnum indexTypeEnum = indexTypeModel.getIndexType(corpid,businessType, saasMark);;

        boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD, indexTypeEnum.getType()));
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.query(boolQueryBuilder);
        PageRequest pageRequest = EsUtil.setPage(sourceBuilder, 1, dataIdList.size());
        SearchRequest searchRequest = new SearchRequest(indexTypeEnum.getIndex());
        searchRequest.source(sourceBuilder);
        XbbAggregatedPage<PaasFormDataEntity> esEntities = xbbElasticsearchRestTemplate.queryForPages(pageRequest,searchRequest,PaasFormDataEntity.class);
        if (Objects.isNull(esEntities)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100404);
        }
        List<PaasFormDataEntity> content = esEntities.getContent();

        return getNameMap(content, businessType, nameOrSeriNoMap);
    }

    public Map<Long, PaasFormDataEntity> getNameMap(List<PaasFormDataEntity> content, Integer businessType, Map<Long, String> nameOrSeriNoMap) throws XbbException{
        Map<Long, PaasFormDataEntity> entityMap = new HashMap<>(content.size());
        if (CollectionsUtil.isEmpty(content)) {
            return entityMap;
        }
        XbbRefTypeEnum xbbRefTypeEnum = XbbRefTypeEnum.getByCode(businessType);
        switch (xbbRefTypeEnum) {
            case CUSTOMER_MANAGEMENT:
                for (PaasFormDataEntity entity : content) {
                    nameOrSeriNoMap.put(entity.getDataId(), FastJsonHelper.getStringOrDefaultFromFormData(entity.getData(), CustomerManagementEnum.NAME.getAttr(), ""));
                    entityMap.put(entity.getDataId(), entity);
                }
                break;
            case SUPPLIER:
                for (PaasFormDataEntity entity : content) {
                    nameOrSeriNoMap.put(entity.getDataId(), FastJsonHelper.getStringOrDefaultFromFormData(entity.getData(), SupplierEnum.SUPPLIER_NAME.getAttr(), ""));
                    entityMap.put(entity.getDataId(), entity);
                }
                break;
            case CLUE:
                for (PaasFormDataEntity entity : content) {
                    nameOrSeriNoMap.put(entity.getDataId(), FastJsonHelper.getStringOrDefaultFromFormData(entity.getData(), ClueEnum.COMPANY_NAME.getAttr(), ""));
                    entityMap.put(entity.getDataId(), entity);
                }
                break;
            case MARKET_ACTIVITY:
                for (PaasFormDataEntity entity : content) {
                    nameOrSeriNoMap.put(entity.getDataId(), FastJsonHelper.getStringOrDefaultFromFormData(entity.getData(), MarketActivityEnum.NAME.getAttr(), ""));
                    entityMap.put(entity.getDataId(), entity);
                }
                break;
            case SUPPLIER_CONTACT:
                for (PaasFormDataEntity entity : content) {
                    nameOrSeriNoMap.put(entity.getDataId(), FastJsonHelper.getStringOrDefaultFromFormData(entity.getData(), SupplierContactEnum.NAME.getAttr(), ""));
                    entityMap.put(entity.getDataId(), entity);
                }
                break;
            case CONTRACT:
            case SALES_OPPORTUNITY:
            case REFUND:
            case QUOTATION:
            case PURCHASE:
            case BOM_BILL:
            case PRODUCTION_ORDER:
            case WORK_ORDER:
            case RETURNED_PURCHASE:
            case ASSEMBLE:
            case TRANSFER:
            case INVENTORY:
            case PURCHASE_INSTOCK:
            case REFUND_INSTOCK:
            case PAYMENT:
            case PREPAY_BALANCE:
            case PREPAYMENT_BALANCE:
            case OTHER_INSTOCK:
            case PRODUCTION_INSTOCK:
            case RETURNED_MATERIEL_INSTOCK:
            case CONTRACT_OUTSTOCK:
            case RETURNED_PURCHASE_OUTSTOCK:
            case PRODUCTION_MATERIEL_OUTSTOCK:
            case OTHER_OUTSTOCK:
            case WORK_ORDER_OUTSTOCK:
            case PAYMENT_SHEET:
            case PAY_SHEET:
            case CONTACT:
            case PAY_PLAN:
            case WAREHOUSE:
            case SYSTEM:
                for (PaasFormDataEntity entity : content) {
                    nameOrSeriNoMap.put(entity.getDataId(), entity.getSerialNo());
                    entityMap.put(entity.getDataId(), entity);
                }
                break;
            default:
                throw new XbbException(BusinessTypeErrorCodeEnum.API_ERROR_361001);
        }
        return entityMap;
    }


    public Map<Long, String> getNameMap(List<PaasFormDataEntityExt> content, Integer businessType) throws XbbException{
        Map<Long, String> nameOrSeriNoMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        if (CollectionsUtil.isEmpty(content)) {
            return nameOrSeriNoMap;
        }
        XbbRefTypeEnum xbbRefTypeEnum = XbbRefTypeEnum.getByCode(businessType);
        switch (xbbRefTypeEnum) {
            case CUSTOMER_MANAGEMENT:
                for (PaasFormDataEntityExt entity : content) {
                    nameOrSeriNoMap.put(entity.getDataId(), FastJsonHelper.getStringOrDefaultFromFormData(entity.getData(), CustomerManagementEnum.NAME.getAttr(), ""));
                }
                break;
            case SUPPLIER:
                for (PaasFormDataEntityExt entity : content) {
                    nameOrSeriNoMap.put(entity.getDataId(), FastJsonHelper.getStringOrDefaultFromFormData(entity.getData(), SupplierEnum.SUPPLIER_NAME.getAttr(), ""));
                }
                break;
            case CLUE:
                for (PaasFormDataEntityExt entity : content) {
                    nameOrSeriNoMap.put(entity.getDataId(), FastJsonHelper.getStringOrDefaultFromFormData(entity.getData(), ClueEnum.COMPANY_NAME.getAttr(), ""));
                }
                break;
            case MARKET_ACTIVITY:
                for (PaasFormDataEntityExt entity : content) {
                    nameOrSeriNoMap.put(entity.getDataId(), FastJsonHelper.getStringOrDefaultFromFormData(entity.getData(), MarketActivityEnum.NAME.getAttr(), ""));
                }
                break;
            case SUPPLIER_CONTACT:
                for (PaasFormDataEntityExt entity : content) {
                    nameOrSeriNoMap.put(entity.getDataId(), FastJsonHelper.getStringOrDefaultFromFormData(entity.getData(), SupplierContactEnum.NAME.getAttr(), ""));
                }
                break;
            case CONTACT:
                for (PaasFormDataEntityExt entity : content) {
                    nameOrSeriNoMap.put(entity.getDataId(), FastJsonHelper.getStringOrDefaultFromFormData(entity.getData(), ContactEnum.NAME.getAttr(), ""));
                }
                break;
            case CONTRACT:
            case SALES_OPPORTUNITY:
            case REFUND:
            case QUOTATION:
            case PURCHASE:
            case BOM_BILL:
            case PRODUCTION_ORDER:
            case WORK_ORDER:
            case RETURNED_PURCHASE:
            case ASSEMBLE:
            case TRANSFER:
            case INVENTORY:
            case PURCHASE_INSTOCK:
            case REFUND_INSTOCK:
            case PAYMENT:
            case PREPAY_BALANCE:
            case PREPAYMENT_BALANCE:
            case OTHER_INSTOCK:
            case PRODUCTION_INSTOCK:
            case RETURNED_MATERIEL_INSTOCK:
            case CONTRACT_OUTSTOCK:
            case RETURNED_PURCHASE_OUTSTOCK:
            case PRODUCTION_MATERIEL_OUTSTOCK:
            case OTHER_OUTSTOCK:
            case WORK_ORDER_OUTSTOCK:
            case PAYMENT_SHEET:
            case PAY_SHEET:
            case PAY_PLAN:
            case WAREHOUSE:
            case SYSTEM:
                for (PaasFormDataEntityExt entity : content) {
                    nameOrSeriNoMap.put(entity.getDataId(), entity.getSerialNo());
                }
                break;
            default:
                throw new XbbException(BusinessTypeErrorCodeEnum.API_ERROR_361001);
        }
        return nameOrSeriNoMap;
    }
    /**
     * 获取时间戳时间
     *
     * @param oldValue
     * @param newValue
     * @return
     */
    public void getStringTime (Long oldValue, Long newValue, List<DetailLogPojo> detailLogPojos) {
        String updataBefore = "";
        String updataAfter = "";
        SimpleDateFormat SDF = new SimpleDateFormat(DateTimeEnum.DATETIME.getType());
        if (Objects.isNull(oldValue)) {
            updataBefore = "";
        }else {
            updataBefore = DateTimeUtil.getStringEpochSecond(oldValue, SDF);
        }
        if (newValue > 0) {
            updataAfter = DateTimeUtil.getStringEpochSecond(newValue, SDF);
        }
        DetailLogPojo detailLogPojo = new DetailLogPojo(I18nMessageUtil.getMessage(CommonConstant.UPDATE_TIME), updataBefore, updataAfter);
        detailLogPojos.add(detailLogPojo);
    }

    /**
     * 获取当前编辑标签是否需要记录日志，如果需要的话，就把几个需要记录的标签id返回
     *
     * @param labels 传参的标签
     * @param dbLabels 数据库存的标签
     * @param lbIdFormList 传参的表单标签id列表
     * @param lbIdSysList 传参的系统标签id列表
     * @param dbLbIdFormList 数据库的表单标签id列表
     * @param dbLbIdSysList 数据库的系统标签id列表
     */
    public boolean getAddLogTag(JSONArray labels, JSONArray dbLabels, List<Long> lbIdFormList, List<Long> lbIdSysList, List<Long> dbLbIdFormList, List<Long> dbLbIdSysList) throws XbbException {
        //表单团队标签每个人上限10个
        if(Objects.nonNull(labels) && labels.size() > BasicConstant.ONE && labels.size() > TeamMembersConstant.USER_LABEL_LIMIT){
            throw new XbbException(UserTeamErrorCodeEnum.API_ERROR_271003);
        }
        if (Objects.nonNull(labels) && labels.size() > BasicConstant.ZERO) {
            for (int i = 0; i < labels.size(); i++) {
                JSONObject labelJson = labels.getJSONObject(i);
                Integer labelType = labelJson.getInteger(BasicConstant.TYPE);
                Long labelId = labelJson.getLong(BasicConstant.ID);
                if (Objects.equals(BasicConstant.ONE, labelType)) {
                    lbIdSysList.add(labelId);
                }else {
                    lbIdFormList.add(labelId);
                }
            }
        }
        if (Objects.nonNull(dbLabels) && dbLabels.size() > BasicConstant.ZERO) {
            for (int i = 0; i < dbLabels.size(); i++) {
                JSONObject labelJson = dbLabels.getJSONObject(i);
                Integer labelType = labelJson.getInteger(BasicConstant.TYPE);
                Long labelId = labelJson.getLong(BasicConstant.ID);
                if (Objects.equals(BasicConstant.ONE, labelType)) {
                    dbLbIdSysList.add(labelId);
                }else {
                    dbLbIdFormList.add(labelId);
                }
            }
        }
        //判断数据库原有标签跟修改后的标签是否一致，求两个集合的差集
        boolean sizeEqualTag = Objects.equals(lbIdFormList.size(), dbLbIdFormList.size()) && Objects.equals(lbIdSysList.size(), dbLbIdSysList.size());
        List<Long> cloneLbIdFormList = (List<Long>) CloneUtil.deepClone(lbIdFormList);
        List<Long> cloneLbIdSysList = (List<Long>) CloneUtil.deepClone(lbIdSysList);
        List<Long> cloneDbLbIdSysList = (List<Long>) CloneUtil.deepClone(dbLbIdSysList);
        List<Long> cloneDbLbIdFormList = (List<Long>) CloneUtil.deepClone(dbLbIdFormList);
        //判断集合有变动的数据
        cloneLbIdFormList.removeAll(cloneDbLbIdFormList);
        cloneLbIdSysList.removeAll(cloneDbLbIdSysList);
        boolean tag = !sizeEqualTag || (sizeEqualTag && CollectionsUtil.isNotEmpty(cloneLbIdFormList)) || (sizeEqualTag && CollectionsUtil.isNotEmpty(cloneLbIdSysList));
        if (tag) {
            //代表需要记录日志
            return true;
        }else {
            //不需要记录日志
            return false;
        }
    }

    /**
     * 判断编辑权限
     *
     * @param userVO 登录员工信息
     * @param paasFormDataEntityExt 表单数据信息
     * @param businessType 业务类型
     * @return boolean true为有权限，false为无权限
     * @throws XbbException 异常
     * @author 徐俊杰
     * @date 2019/7/4 11:09
     * @since v1.0
     */
    public boolean checkEditPermission(UserVO userVO, PaasFormDataEntityExt paasFormDataEntityExt, Integer businessType) throws XbbException {
        UserEntity userEntity = new UserEntity();
        BeanUtil.copyProperties(userVO, userEntity);
        // 超管和老板
        if (userVO.isAdminOrBoss()) {
            return true;
        }
        //基本数据
        Long dataId = paasFormDataEntityExt.getId();
        String corpid = userEntity.getCorpid();
        List<String> userIdIn;
        Integer dataPermission = userModel.getDataPermission(userEntity, SaasMarkEnum.SAAS, businessType, null);
        if (Objects.equals(dataPermission, DataPermissionEnum.SELF.getCode())) {
            //数据权限为本人时
            userIdIn = Collections.singletonList(userVO.getUserId());
        } else {
            //数据权限不为本人时，需要判断下属员工是否是负责人
            userIdIn = userModel.getSubIdListByDataPermission(dataPermission, userVO.getUserId(), userVO.getCorpid(), BasicConstant.ONE, false);
        }
        XbbRefTypeEnum xbbRefTypeEnum = XbbRefTypeEnum.getByCode(businessType);
        BoolQueryBuilder boolQueryBuilder = boolQuery();
        switch (xbbRefTypeEnum){
            case CONTRACT:
                // 数据权限为全公司并且有合同编辑权限，可以编辑
                if (userVO.isMaxDataPermission() && userVO.getPermSet().contains(ProPermissionAliasEnum.CONTRACT_UPDATE.getAlias())) {
                    return true;
                }
                //编辑权限判断
                UserTeamEnum byCode = UserTeamEnum.getByCode(businessType);
                IndexTypeEnum indexTypeEnum = byCode.getIndexTypeEnum();
                boolQueryBuilder.filter(termQuery("corpid.keyword", corpid));
                boolQueryBuilder.filter(termQuery(SubFormTransferEnum.getEsAttrByIndexTypeAndDbAttr(indexTypeEnum, FieldTypeEnum.DATAID.getAlias()), dataId));
                boolQueryBuilder.filter(termQuery("del", DelEnum.NORMAL.getDel()));
                boolQueryBuilder.filter(termsQuery(SubFormTransferEnum.getEsAttrByIndexTypeAndDbAttr(indexTypeEnum, ParameterConstant.USER_ID), userIdIn));
                boolQueryBuilder.filter(termQuery(SubFormTransferEnum.getEsAttrByIndexTypeAndDbAttr(indexTypeEnum, ParameterConstant.IS_MAIN), BasicConstant.MAIN_USER));
                ElasticAggsPojo elasticAggsPojo = esHelper.elasticAggs(indexTypeEnum, boolQueryBuilder, null);
                return StringUtil.toInt(elasticAggsPojo.getTotal(), 0) > 0;
            default:
                return true;
        }
    }

    public boolean teamMembersCheckEditPermission(UserVO userVO, PaasFormEntityExt paasFormEntityExt, Map<String, FieldAttrEntity> explainMap) throws XbbException {
        FormDataDetailDTO formDataDetailDTO = new FormDataDetailDTO();
        formDataDetailDTO.setLoginUser(userVO);
        formDataDetailDTO.setSaasMark(paasFormEntityExt.getSaasMark());
        formDataDetailDTO.setBusinessType(paasFormEntityExt.getBusinessType());
        formDataDetailDTO.setMenuId(paasFormEntityExt.getMenuId());
        formDataDetailDTO.setDistributorMark(paasFormEntityExt.getDistributorMark());
        return teamMembersCheckEditPermission(formDataDetailDTO, explainMap);
    }

    /**
     *
     * 详情页的编辑权限判断，上面的checkEditPermission留着用于给经销商那边的订单使用。
     * 团队成员这边的需求主要是：（1）全公司、老板、超管
     *                      （2）主管在团队中的需要依据在团队中能否编辑
     *                      （3）主管不在团队中都能编辑
     *                      （4）数据权限仅本人的话依据在团队中的权限
     *
     *
     * @param formDataDetailDTO 数据库查询出来的数据
     * @param explainMap 业务类型
     * @return
     */
    public boolean teamMembersCheckEditPermission(FormDataDetailDTO formDataDetailDTO, Map<String, FieldAttrEntity> explainMap) throws XbbException {
        Integer businessType = formDataDetailDTO.getBusinessType();
        Integer saasMark = formDataDetailDTO.getSaasMark();
        Long menuId = formDataDetailDTO.getMenuId();
        UserVO userVO = formDataDetailDTO.getLoginUser();
        List<Integer> allBusinessTypeList = TeamEditBusinessEnum.getAllBusinessType();
        if (Objects.equals(DistributorMarkEnum.DISTRIBUTOR.getCode(), formDataDetailDTO.getDistributorMark())) {
            return true;
        }
        UserEntity userEntity = new UserEntity();
        BeanUtil.copyProperties(userVO, userEntity);
        Integer dataPermission = userModel.getDataPermission(userEntity, SaasMarkEnum.getByCode(saasMark), businessType, menuId);
        Boolean isAdminOrBoss = userVO.isAdminOrBoss();
        Boolean hasMaxPermission = Objects.equals(DataPermissionEnum.ALL.getCode(), dataPermission);
        if (isAdminOrBoss) {
            return true;
        }
        if (hasMaxPermission) {
            return true;
        }
        FieldAttrEntity ownerIdField = explainMap.get(FieldTypeEnum.OWNERID.getAlias());
        FieldAttrEntity coUserIdField = explainMap.get(FieldTypeEnum.COUSERID.getAlias());
        if (Objects.equals(SaasMarkEnum.PAAS.getCode(), saasMark) && (Objects.isNull(ownerIdField) || Objects.isNull(coUserIdField))) {
            //Paas表单无负责人/协同人时,创建人或创建人的上级才有团队权限
            Map<String, Integer> dataPermissionDetail = userVO.getDataPermissionDetail();
            Integer formDataPermission = dataPermissionDetail.get(saasMark + StringConstant.UNDER_LINE + formDataDetailDTO.getMenuId());
            List<String> subUserIds = userModel.getSubIdListByDataPermission(formDataPermission, userVO.getUserId(), userVO.getCorpid(), BasicConstant.ONE, false);
            return subUserIds.contains(formDataDetailDTO.getDataCreatorId());
        }
        //查询团队用户信息
        List<UserTeamEntity> userTeamEntities = new ArrayList<>();
        List<String> teamUserIds = new ArrayList<>();
        userTeamEntities = getUserTeamList(Arrays.asList(formDataDetailDTO.getDataId()), userVO.getCorpid(), businessType, Boolean.FALSE, null);
        Map<String, UserTeamEntity> userTeamEntityMap = new HashMap<>(userTeamEntities.size() * 2);
        if (CollectionsUtil.isNotEmpty(userTeamEntities)) {
            userTeamEntityMap = userTeamEntities.stream().collect(Collectors.toMap(UserTeamEntity:: getUserId, a -> a, (k1, k2) -> k1));
            teamUserIds = userTeamEntities.stream().map(UserTeamEntity::getUserId).collect(Collectors.toList());
        }
        UserTeamEntity userTeamEntity = userTeamEntityMap.get(userVO.getUserId());
        if (Objects.isNull(userTeamEntity)) {
            //是本团队某一人员的上级才有团队权限
            Map<String, Integer> dataPermissionDetail = userVO.getDataPermissionDetail();
            Integer formDataPermission = Objects.equals(saasMark, SaasMarkEnum.SAAS.getCode()) ?
                    dataPermissionDetail.get(saasMark + StringConstant.UNDER_LINE + businessType) :
                    dataPermissionDetail.get(saasMark + StringConstant.UNDER_LINE + formDataDetailDTO.getMenuId());
            List<String> subUserIds = userModel.getSubIdListByDataPermission(formDataPermission, userVO.getUserId(), userVO.getCorpid(), BasicConstant.ONE, true);
            return CollectionUtils.intersection(teamUserIds, subUserIds).size() > BasicConstant.ZERO;
        }else {
            Integer isMain = userTeamEntity.getIsMain();
            if (Objects.equals(BasicConstant.ONE, isMain)) {
                //负责人都是可编辑的
                return true;
            }else if (Objects.equals(BasicConstant.ZERO, isMain)) {
                //如果是协同人就需要判断当前协同人是不是有编辑权限
                Integer formPermission = userTeamEntity.getFormPermission();
                if (Objects.isNull(formPermission)) {
                    formPermission = FormCoUserDefaultPermissionEnum.getDefaultPerByBus(businessType);
                }
                if (Objects.equals(CoUserPermissionEnum.READ.getPermissionValue(), formPermission)) {
                    return false;
                }else {
                    return true;
                }
            }
        }
        return true;
    }


    /**
     * 批量编辑的时候对编辑按钮的控制
     *
     * @param businessType
     * @param saasMark
     * @param menuId
     * @param userVO
     * @param distributorMark
     * @param dataIdIn
     * @param explainMap
     * @return 返回没有编辑权的数据，就是有问题的errorDataId
     */
    public List<Long> batchTeamMembersCheckEditPermission(Integer businessType, Integer saasMark, Long menuId, UserVO userVO, Integer distributorMark,
                                                       List<Long> dataIdIn, Map<String, FieldAttrEntity> explainMap) {
        List<Long> errorDataIdList = new ArrayList<>();
        List<Integer> allBusinessTypeList = TeamEditBusinessEnum.getAllBusinessType();
        if (!allBusinessTypeList.contains(businessType)) {
            return errorDataIdList;
        }
        //到了这一步肯定拥有业务的表单权限，所以就不需要判断表单的表单权限了
        if (Objects.equals(DistributorMarkEnum.DISTRIBUTOR.getCode(), distributorMark)) {
            return errorDataIdList;
        }
        if (Objects.equals(SaasMarkEnum.PAAS.getCode(), saasMark)) {
            FieldAttrEntity ownerIdField = explainMap.get(FieldTypeEnum.OWNERID.getAlias());
            FieldAttrEntity coUserIdField = explainMap.get(FieldTypeEnum.COUSERID.getAlias());
            if ((Objects.isNull(ownerIdField) || Objects.isNull(coUserIdField))) {
                return errorDataIdList;
            }
        }
        UserEntity userEntity = new UserEntity();
        BeanUtil.copyProperties(userVO, userEntity);
        Integer dataPermission = userModel.getDataPermission(userEntity, SaasMarkEnum.getByCode(saasMark), businessType, menuId);
        Boolean isAdminOrBoss = userVO.isAdminOrBoss();
        Boolean hasMaxPermission = Objects.equals(DataPermissionEnum.ALL.getCode(), dataPermission);
        if (isAdminOrBoss) {
            return errorDataIdList;
        }
        if (hasMaxPermission) {
            return errorDataIdList;
        }
        //查询团队用户信息
        List<UserTeamEntity> userTeamEntities = new ArrayList<>();
        userTeamEntities = getUserTeamList(dataIdIn, userVO.getCorpid(), businessType, Boolean.FALSE, null);
        if (CollectionsUtil.isEmpty(userTeamEntities)) {
            return errorDataIdList;
        }
        Map<Long, List<UserTeamEntity>> userMap = userTeamEntities.stream().collect(Collectors.groupingBy(UserTeamEntity::getDataId));
        for (Long dataId : dataIdIn) {
            List<UserTeamEntity> dataIdUserTeamEntityList = userMap.get(dataId);
            if (CollectionsUtil.isEmpty(dataIdUserTeamEntityList)) {
                continue;
            }
            Map<String, UserTeamEntity> dataIdUserTeamEntityMap = dataIdUserTeamEntityList.stream().collect(Collectors.toMap(UserTeamEntity:: getUserId, a -> a, (k1, k2) -> k1));;
            UserTeamEntity userTeamEntity = dataIdUserTeamEntityMap.get(userVO.getUserId());
            if (Objects.isNull(userTeamEntity)) {
                continue;
            }else {
                Integer isMain = userTeamEntity.getIsMain();
                if (Objects.equals(BasicConstant.ONE, isMain)) {
                    //负责人都是可编辑的
                    continue;
                }else if (Objects.equals(BasicConstant.ZERO, isMain)) {
                    //如果是协同人就需要判断当前协同人是不是有编辑权限
                    Integer formPermission = userTeamEntity.getFormPermission();
                    if (Objects.isNull(formPermission)) {
                        formPermission = FormCoUserDefaultPermissionEnum.getDefaultPerByBus(businessType);
                    }
                    if (Objects.equals(CoUserPermissionEnum.READ.getPermissionValue(), formPermission)) {
                        errorDataIdList.add(dataId);
                        continue;
                    }else {
                        continue;
                    }
                }
            }
        }
        return errorDataIdList;
    }
}
